home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / File / SearchReplace.php < prev    next >
PHP Script  |  2004-03-24  |  15KB  |  459 lines

  1. <?php
  2. // +-----------------------------------------------------------------------+
  3. // | Copyright (c) 2002, Richard Heyes                                     |
  4. // | All rights reserved.                                                  |
  5. // |                                                                       |
  6. // | Redistribution and use in source and binary forms, with or without    |
  7. // | modification, are permitted provided that the following conditions    |
  8. // | are met:                                                              |
  9. // |                                                                       |
  10. // | o Redistributions of source code must retain the above copyright      |
  11. // |   notice, this list of conditions and the following disclaimer.       |
  12. // | o Redistributions in binary form must reproduce the above copyright   |
  13. // |   notice, this list of conditions and the following disclaimer in the |
  14. // |   documentation and/or other materials provided with the distribution.|
  15. // | o The names of the authors may not be used to endorse or promote      |
  16. // |   products derived from this software without specific prior written  |
  17. // |   permission.                                                         |
  18. // |                                                                       |
  19. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
  20. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
  21. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
  22. // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
  23. // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
  24. // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
  25. // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
  26. // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
  27. // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
  28. // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
  29. // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
  30. // |                                                                       |
  31. // +-----------------------------------------------------------------------+
  32. // | Author: Richard Heyes <richard@phpguru.org>                           |
  33. // +-----------------------------------------------------------------------+
  34. //
  35. // $Id: SearchReplace.php,v 1.1 2002/04/21 19:38:32 richard Exp $
  36. //
  37. // Search and Replace Utility
  38. //
  39.  
  40. /**
  41.  * Search and Replace Utility
  42.  *
  43.  *
  44.  * @author  Richard Heyes <richard@phpguru.org>
  45.  * @version 1.0
  46.  * @package File
  47.  */
  48. class File_SearchReplace
  49. {
  50.     
  51.     // {{{ Properties (All private)
  52.  
  53.     var $find;
  54.     var $replace;
  55.     var $files;
  56.     var $directories;
  57.     var $include_subdir;
  58.     var $ignore_lines;
  59.     var $ignore_sep;
  60.     var $occurences;
  61.     var $search_function;
  62.     var $last_error;
  63.  
  64.     // }}}
  65.     // {{{ Constructor
  66.  
  67.     /**
  68.      * Sets up the object
  69.      *
  70.      * @access public
  71.      * @param string $find                      The string/regex to find.
  72.      * @param string $replace                   The string/regex to replace $find with.
  73.      * @param array  $files                     The file(s) to perform this operation on.
  74.      * @param array  $directories    (optional) The directories to perform this operation on.
  75.      * @param int    $include_subdir            If performing on directories, whether to traverse subdirectories.
  76.      * @param array  $ignore_lines              Ignore lines beginning with any of the strings in this array. This
  77.      *                                          feature only works with the "normal" search.
  78.      */
  79.     function File_SearchReplace($find, $replace, $files, $directories = '', $include_subdir = 1, $ignore_lines = array())
  80.     {
  81.  
  82.         $this->find            = $find;
  83.         $this->replace         = $replace;
  84.         $this->files           = $files;
  85.         $this->directories     = $directories;
  86.         $this->include_subdir  = $include_subdir;
  87.         $this->ignore_lines    = $ignore_lines;
  88.  
  89.         $this->occurences      = 0;
  90.         $this->search_function = 'search';
  91.         $this->last_error      = '';
  92.  
  93.     }
  94.  
  95.     // }}}
  96.     // {{{ getNumOccurences()
  97.  
  98.     /**
  99.      * Accessor to return the number of occurences found.
  100.      *
  101.      * @access public
  102.      * @return int Number of occurences found.
  103.      */
  104.     function getNumOccurences()
  105.     {
  106.         return $this->occurences;
  107.     }
  108.  
  109.     // }}}
  110.     // {{{ getLastError()
  111.  
  112.     /**
  113.      * Accessor for retrieving last error.
  114.      *
  115.      * @access public
  116.      * @return string The last error that occurred, if any.
  117.      */
  118.     function getLastError()
  119.     {
  120.         return $this->last_error;
  121.     }
  122.  
  123.     // }}}
  124.     // {{{ setFind()
  125.  
  126.     /**
  127.      * Accessor for setting find variable.
  128.      *
  129.      * @access public
  130.      * @param string $find The string/regex to find.
  131.      */
  132.     function setFind($find)
  133.     {
  134.         $this->find = $find;
  135.     }
  136.  
  137.     // }}}
  138.     // {{{ setReplace()
  139.  
  140.     /**
  141.      * Accessor for setting replace variable.
  142.      *
  143.      * @access public
  144.      * @param string $replace The string/regex to replace the find string/regex with.
  145.      */
  146.     function setReplace($replace)
  147.     {
  148.         $this->replace = $replace;
  149.     }
  150.  
  151.     // }}}
  152.     // {{{ setFiles()
  153.  
  154.     /**
  155.      * Accessor for setting files variable.
  156.      *
  157.      * @access public
  158.      * @param array $files The file(s) to perform this operation on.
  159.      */
  160.     function setFiles($files)
  161.     {
  162.         $this->files = $files;
  163.     }
  164.  
  165.     // }}}
  166.     // {{{ setDirectories()
  167.  
  168.     /**
  169.      * Accessor for setting directories variable.
  170.      *
  171.      * @access public
  172.      * @param array $directories The directories to perform this operation on.
  173.      */
  174.     function setDirectories($directories)
  175.     {
  176.         $this->directories = $directories;
  177.     }
  178.  
  179.     // }}}
  180.     // {{{ setIncludeSubdir
  181.  
  182.     /**
  183.      * Accessor for setting include_subdir variable.
  184.      *
  185.      * @access public
  186.      * @param int $include_subdir Whether to traverse subdirectories or not.
  187.      */
  188.     function setIncludeSubdir($include_subdir)
  189.     {
  190.         $this->include_subdir = $include_subdir;
  191.     }
  192.  
  193.     // }}}
  194.     // {{{ setIgnoreLines()
  195.  
  196.     /**
  197.      * Accessor for setting ignore_lines variable.
  198.      *
  199.      * @access public
  200.      * @param array $ignore_lines Ignore lines beginning with any of the strings in this array. This
  201.      *                            feature only works with the "normal" search.
  202.      */
  203.     function setIgnoreLines($ignore_lines)
  204.     {
  205.         $this->ignore_lines = $ignore_lines;
  206.     }
  207.  
  208.     // }}}
  209.     // {{{ setSearchFunction()
  210.  
  211.     /**
  212.      * Function to determine which search function is used.
  213.      *
  214.      * @access public
  215.      * @param string The search function that should be used. Can be any one of:
  216.      *               normal - Default search. Goes line by line. Ignore lines feature only works with this type.
  217.      *               quick  - Uses str_replace for straight replacement throughout file. Quickest of the lot.
  218.      *               preg   - Uses preg_replace(), so any regex valid with this function is valid here.
  219.      *               ereg   - Uses ereg_replace(), so any regex valid with this function is valid here.
  220.      */
  221.     function setSearchFunction($search_function)
  222.     {
  223.         switch($search_function) {
  224.         case 'normal': $this->search_function = 'search';
  225.             return TRUE;
  226.             break;
  227.  
  228.         case 'quick' : $this->search_function = 'quickSearch';
  229.             return TRUE;
  230.             break;
  231.  
  232.         case 'preg'  : $this->search_function = 'pregSearch';
  233.             return TRUE;
  234.             break;
  235.  
  236.         case 'ereg'  : $this->search_function = 'eregSearch';
  237.             return TRUE;
  238.             break;
  239.  
  240.         default      : $this->last_error      = 'Invalid search function specified';
  241.             return FALSE;
  242.             break;
  243.         }
  244.     }
  245.  
  246.     // }}}
  247.     // {{{ search()
  248.  
  249.     /**
  250.      * Default ("normal") search routine.
  251.      *
  252.      * @access private
  253.      * @param string $filename The filename to search and replace upon.
  254.      * @return array Will return an array containing the new file contents and the number of occurences.
  255.      *               Will return FALSE if there are no occurences.
  256.      */
  257.     function search($filename)
  258.     {
  259.  
  260.         $occurences = 0;
  261.         $file_array = file($filename);
  262.  
  263.         for ($i=0; $i<count($file_array); $i++) {
  264.  
  265.             if (count($this->ignore_lines) > 0) {
  266.                 for ($j=0; $j<count($this->ignore_lines); $j++) {
  267.                     if (substr($file_array[$i],0,strlen($this->ignore_lines[$j])) == $this->ignore_lines[$j]) continue 2;
  268.                 }
  269.             }
  270.  
  271.             $occurences += count(explode($this->find, $file_array[$i])) - 1;
  272.             $file_array[$i] = str_replace($this->find, $this->replace, $file_array[$i]);
  273.         }
  274.         if ($occurences > 0) $return = array($occurences, implode('', $file_array)); else $return = FALSE;
  275.         return $return;
  276.  
  277.     }
  278.  
  279.     // }}}
  280.     // {{{ quickSearch()
  281.  
  282.     /**
  283.      * Quick search routine.
  284.      *
  285.      * @access private
  286.      * @param string $filename The filename to search and replace upon.
  287.      * @return array Will return an array containing the new file contents and the number of occurences.
  288.      *               Will return FALSE if there are no occurences.
  289.      */
  290.     function quickSearch($filename)
  291.     {
  292.  
  293.         clearstatcache();
  294.  
  295.         $file       = fread($fp = fopen($filename, 'r'), filesize($filename)); fclose($fp);
  296.         $occurences = count(explode($this->find, $file)) - 1;
  297.         $file       = str_replace($this->find, $this->replace, $file);
  298.  
  299.         if ($occurences > 0) $return = array($occurences, $file); else $return = FALSE;
  300.         return $return;
  301.  
  302.     }
  303.  
  304.     // }}}
  305.     // {{{ pregSearch()
  306.  
  307.     /**
  308.      * Preg search routine.
  309.      *
  310.      * @access private
  311.      * @param string $filename The filename to search and replace upon.
  312.      * @return array Will return an array containing the new file contents and the number of occurences.
  313.      *               Will return FALSE if there are no occurences.
  314.      */
  315.     function pregSearch($filename)
  316.     {
  317.  
  318.         clearstatcache();
  319.  
  320.         $file       = fread($fp = fopen($filename, 'r'), filesize($filename)); fclose($fp);
  321.         $occurences = count($matches = preg_split($this->find, $file)) - 1;
  322.         $file       = preg_replace($this->find, $this->replace, $file);
  323.  
  324.         if ($occurences > 0) $return = array($occurences, $file); else $return = FALSE;
  325.         return $return;
  326.  
  327.     }
  328.  
  329.     // }}}
  330.     // {{{ eregSearch()
  331.  
  332.     /**
  333.      * Ereg search routine.
  334.      *
  335.      * @access private
  336.      * @param string $filename The filename to search and replace upon.
  337.      * @return array Will return an array containing the new file contents and the number of occurences.
  338.      *               Will return FALSE if there are no occurences.
  339.      */
  340.     function eregSearch($filename)
  341.     {
  342.  
  343.         clearstatcache();
  344.  
  345.         $file = fread($fp = fopen($filename, 'r'), filesize($filename)); fclose($fp);
  346.  
  347.         $occurences = count($matches = split($this->find, $file)) -1;
  348.         $file       = ereg_replace($this->find, $this->replace, $file);
  349.  
  350.         if ($occurences > 0) $return = array($occurences, $file); else $return = FALSE;
  351.         return $return;
  352.  
  353.     }
  354.  
  355.     // }}}
  356.     // {{{ writeout()
  357.     
  358.     /**
  359.      * Function to writeout the file contents.
  360.      *
  361.      * @access private
  362.      * @param string $filename The filename of the file to write.
  363.      * @param string $contents The contents to write to the file.
  364.      */
  365.     function writeout($filename, $contents)
  366.     {
  367.  
  368.         if ($fp = @fopen($filename, 'w')) {
  369.             flock($fp,2);
  370.             fwrite($fp, $contents);
  371.             flock($fp,3);
  372.             fclose($fp);
  373.         } else {
  374.             $this->last_error = 'Could not open file: '.$filename;
  375.         }
  376.  
  377.     }
  378.  
  379.     // }}}
  380.     // {{{ doFiles()
  381.  
  382.     /**
  383.      * Function called by doSearch() to go through any files that need searching.
  384.      *
  385.      * @access private
  386.      * @param string $ser_func The search function to use.
  387.      */
  388.     function doFiles($ser_func)
  389.     {
  390.         if (!is_array($this->files)) $this->files = explode(',', $this->files);
  391.         for ($i=0; $i<count($this->files); $i++) {
  392.             if ($this->files[$i] == '.' OR $this->files[$i] == '..') continue;
  393.             if (is_dir($this->files[$i]) == TRUE) continue;
  394.             $newfile = $this->$ser_func($this->files[$i]);
  395.             if (is_array($newfile) == TRUE){
  396.                 $this->writeout($this->files[$i], $newfile[1]);
  397.                 $this->occurences += $newfile[0];
  398.             }
  399.         }
  400.     }
  401.  
  402.     // }}}
  403.     // {{{ doDirectories()
  404.  
  405.     /**
  406.      * Function called by doSearch() to go through any directories that need searching.
  407.      *
  408.      * @access private
  409.      * @param string $ser_func The search function to use.
  410.      */
  411.     function doDirectories($ser_func)
  412.     {
  413.         if (!is_array($this->directories)) $this->directories = explode(',', $this->directories);
  414.         for ($i=0; $i<count($this->directories); $i++) {
  415.             $dh = opendir($this->directories[$i]);
  416.             while ($file = readdir($dh)) {
  417.                 if ($file == '.' OR $file == '..') continue;
  418.  
  419.                 if (is_dir($this->directories[$i].$file) == TRUE) {
  420.                     if ($this->include_subdir == 1) {
  421.                         $this->directories[] = $this->directories[$i].$file.'/';
  422.                         continue;
  423.                     } else {
  424.                         continue;
  425.                     }
  426.                 }
  427.  
  428.                 $newfile = $this->$ser_func($this->directories[$i].$file);
  429.                 if (is_array($newfile) == TRUE) {
  430.                     $this->writeout($this->directories[$i].$file, $newfile[1]);
  431.                     $this->occurences += $newfile[0];
  432.                 }
  433.             }
  434.         }
  435.     }
  436.  
  437.     // }}}
  438.     // {{{ doSearch()
  439.     
  440.     /**
  441.      * This starts the search/replace off. Call this to do the search.
  442.      * First do whatever files are specified, and/or if directories are specified,
  443.      * do those too.
  444.      *
  445.      * @access public
  446.      */
  447.     function doSearch()
  448.     {
  449.         if ($this->find != '') {
  450.             if ((is_array($this->files) AND count($this->files) > 0) OR $this->files != '') $this->doFiles($this->search_function);
  451.             if ($this->directories != '')                                                   $this->doDirectories($this->search_function);
  452.         }
  453.     }
  454.     
  455.     // }}}
  456.  
  457. }
  458. ?>
  459.